<?php
declare(strict_types=1);
/**
 * MineAdmin is committed to providing solutions for quickly building web applications
 * Please view the LICENSE file that was distributed with this source code,
 * For the full copyright and license information.
 * Thank you very much for using MineAdmin.
 *
 * @Author X.Mo<root@imoi.cn>
 * @Link   https://gitee.com/xmo/MineAdmin
 */

namespace Plugin\Organization\Service;

use App\Exception\BusinessException;
use App\Http\Common\ResultCode;
use App\Service\IService;
use Hyperf\DbConnection\Db;
use Plugin\Organization\Repository\RdOrganizeAreaRepository;
use Plugin\Organization\Repository\RdOrganizeAreaStandRepository;
use Plugin\Organization\Repository\RdOrganizeProjLineRepository;
use Plugin\Organization\Repository\RdOrganizeUserApplyRepository;
use Plugin\Organization\Repository\RdOrganizeUserStandRepository;

/**
 * 用户权限申请服务类
 */
final class RdOrganizeUserApplyService extends IService
{
    public function __construct(
        protected readonly RdOrganizeUserApplyRepository $repository,
        protected readonly RdOrganizeProjLineRepository  $projLineRepository,
        protected readonly RdOrganizeAreaRepository      $areaRepository,
        protected readonly RdOrganizeAreaStandRepository $areaStandRepository,
        protected readonly RdOrganizeUserStandRepository $userStandRepository
    )
    {
    }

    public function getAllowedUpdateData($data): array
    {
        return array_flip(['status', 'apply_data']);
    }

    public function create(array $data): mixed
    {
        switch ($data['area']) {
            case 1:
                $rep = $this->projLineRepository;
                break;
            case 2:
                $rep = $this->areaRepository;
                break;
            case 3:
                $rep = $this->areaStandRepository;
                break;
            default:
                return false;
        }
        $existIds = $rep->getQuery()
            ->whereIn('id', $data['area_ids'])->where('status', 1)
            ->pluck('id')->toArray();
        $notExistIds = array_diff($data['area_ids'], $existIds);
        if (count($notExistIds) > 0) {
            throw new BusinessException(ResultCode::NOT_FOUND, '所选区域不存在:' . implode(',', $notExistIds));
        }
//        存在未处理申请，覆盖
        if ($apply = $this->repository->findByFilter([
            'user_id' => $data['user_id'],
            'status' => 1,
        ])) {
            return $apply->update([
                'area' => $data['area'],
                'area_ids' => $data['area_ids'],
                'remark' => $data['remark'] ?? '',
                'role' => $data['role'],
                'name' => $data['name'],
                'apply_data' => $data['apply_data'] ?? [],
            ]);
        }
        return $this->repository->create([
            'user_id' => $data['user_id'],
            'area' => $data['area'],
            'area_ids' => $data['area_ids'],
            'status' => 1,
            'remark' => $data['remark'] ?? '',
            'role' => $data['role'],
            'name' => $data['name'],
            'apply_data' => $data['apply_data'] ?? [],
        ]);
    }

    public function apply(array $data)
    {
        $id = $data['id'];
        $status = $data['status'];
        $remark = $data['remark'] ?? '';
        $ids = $data['ids'] ?? [];
        $apply = $this->repository->getQuery()->find($id);
        if (!$apply) {
            throw new BusinessException(ResultCode::NOT_FOUND, '申请不存在');
        }
        if ($apply->status != 1) {
            throw new BusinessException(ResultCode::FAIL, '申请已处理');
        }
        Db::beginTransaction();
        try {
            if ($status == 2) {
//                同意申请
//                $ids = $this->areaStandRepository->getStandIds($apply->area, $apply->area_ids);
                if (!empty($ids)) {
                    foreach ($ids as $standId) {
                        if ($this->userStandRepository->findByFilter(['user_id' => $apply->user_id, 'stand_id' => $standId['s']])) {
                            continue;
                        }
                        $this->userStandRepository->create([
                            'user_id' => $apply->user_id,
                            'stand_id' => $standId['s'],
                            'role' => $standId['r'],
                            'status' => 1,
                        ]);
                    }
                }
            }
            $apply->update(['status' => $status, 'apply_id' => $data['user_id'], 'remark' => $remark, 'apply_data' => $ids]);
            Db::commit();
        } catch(\Throwable $e) {
            Db::rollBack();
            throw new BusinessException(ResultCode::FAIL, '操作失败:' . $e->getMessage());
        }
        return true;
    }

    public function detail(int $id)
    {
        return $this->repository->findByFilter(['user_id' => $id]) ?? null;
    }
}